//
//  AWHttpService.m
//  ArtWin
//
//  Created by YYS on 2020/8/4.
//  Copyright © 2020 YYS. All rights reserved.
//

#import "AWHttpService.h"
#import <AFNetworking.h>
#import "SVProgressHUD.h"
#import "DeviceModelUtil.h"
#import "NSString+EncodingData.h"

@interface AWHttpService ()

@property (nonatomic,strong)  AFHTTPSessionManager *session;
@property (nonatomic,retain)  NSURLSessionTask *task;

@end

@implementation AWHttpService

static NSMutableArray *gy_requestTasks;  /*存放请求线程*/

+ (AWHttpService *)service {
    static AWHttpService *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[AWHttpService alloc]init];
    });
    return instance;
}

#pragma mark public
- (void)postWithUrl:(NSString *)url params:(id)param succ:(SuccessBlock)succ fail:(FailureBlock)fail {
    [self configFailedNet];
    
    if (![url isEqualToString:@"/trains/simulate"] &&
        ![url isEqualToString:@"/trains/variety"] &&
        ![url isEqualToString:@"/trains/callback"] &&
        ![url isEqualToString:@"/trains/desire"] &&
        ![url isEqualToString:@"/trains/parent"]) {
        [SVProgressHUD show];
    }

    NSString *urlString = @"";
    if ([url isEqualToString:@"/trains/incorrect"]) {
        urlString = [NSString stringWithFormat:@"http://47.236.132.190/owner%@",url];
    }else {
        urlString = [NSString stringWithFormat:@"http://47.236.132.190/owner%@",url];
    }
    NSString *postUrl = [NSString stringWithFormat:@"%@?overhead=%@&locations=%@&relative=%@&immediately=%@&mitigate=%@&techniques=%@&narrowly=%@",urlString,[NSString stringWithFormat:@"%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]],[DeviceModelUtil deviceMarketingName],[AppTools getOrCreatePseudoIDFV],[NSString stringWithFormat:@"%@",[[UIDevice currentDevice] systemVersion]],[AppTools getLoginToken],[AppTools getIDFA],[AppTools getLoginCountry]];
    
    NSCharacterSet *allowedCharacterSet = [NSCharacterSet URLQueryAllowedCharacterSet];
    NSString *escapedString = [postUrl stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
    
    NSDictionary *headers = @{};
    
    [self.session POST:escapedString
            parameters:param
               headers:headers
              progress:nil
               success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (succ){
            NSString *rawString = [[NSString alloc] encodingData:responseObject];
            NSDictionary *responseDic = [AppTools dictionaryWithJsonString:rawString];
            DLog(@"Request========\n%@\n\nparam========\n%@\n\nresponseObject========\n%@",urlString,param,responseDic);
            NSString *interchangeably = [NSString stringWithFormat:@"%@",[responseDic safeObjectForKey:@"interchangeably"]];
            if ([interchangeably isEqualToString:@"-2"]) {
                [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"user_token"];
                [[NSUserDefaults standardUserDefaults] synchronize];
                
                [AppTools toLogin];
                [SVProgressHUD showErrorWithStatus:[Lang set:@"Login invalid"]];
                [SVProgressHUD dismissWithDelay:3.0f];

            }
            [SVProgressHUD dismiss];
            succ(responseDic);
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self hideTip];
        NSInteger errorType = ReqCodeTypeOther;
        if (error.code == NSURLErrorTimedOut) errorType = ReqCodeTypeTimeout;
        if (error.code == NSURLErrorCancelled) errorType = ReqCodeTypeCalceled;
        if (error.code == NSURLErrorNotConnectedToInternet || error.code == NSURLErrorCannotConnectToHost) errorType = ReqCodeTypeNoNetWork;
        
        if (errorType == ReqCodeTypeTimeout || errorType == ReqCodeTypeNoNetWork) {
            if (![url isEqualToString:@"/trains/simulate"] &&
                ![url isEqualToString:@"/trains/variety"] &&
                ![url isEqualToString:@"/trains/callback"] &&
                ![url isEqualToString:@"/trains/desire"] &&
                ![url isEqualToString:@"/trains/parent"]) {
                [SVProgressHUD showErrorWithStatus:[Lang set:@"There's an error in the network"]];
                [SVProgressHUD dismissWithDelay:3.0f];

            }
        }else{
            if (![url isEqualToString:@"/trains/simulate"] &&
                ![url isEqualToString:@"/trains/variety"] &&
                ![url isEqualToString:@"/trains/callback"] &&
                ![url isEqualToString:@"/trains/desire"] &&
                ![url isEqualToString:@"/trains/parent"]) {
                [SVProgressHUD showErrorWithStatus:[Lang set:@"Request failed"]];
                [SVProgressHUD dismissWithDelay:3.0f];

            }
        }
        if (fail) {
            fail(errorType,error);
        }
    }];
}

+ (void)uploadImage:(NSData *)imageData params:(NSDictionary *)params imageName:(NSString *)imageName completion:(void(^)(NSData *, NSURLResponse *, NSError *))completion {
    
    NSString *urlString = @"http://47.236.132.190/owner/trains/engine";
    
    NSString *postUrl = [NSString stringWithFormat:@"%@?overhead=%@&locations=%@&relative=%@&immediately=%@&mitigate=%@&techniques=%@&narrowly=%@",urlString,[NSString stringWithFormat:@"%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]],[DeviceModelUtil deviceMarketingName],[AppTools getOrCreatePseudoIDFV],[NSString stringWithFormat:@"%@",[[UIDevice currentDevice] systemVersion]],[AppTools getLoginToken],[AppTools getIDFA],[AppTools getLoginCountry]];
    
    NSCharacterSet *allowedCharacterSet = [NSCharacterSet URLQueryAllowedCharacterSet];
    NSString *escapedString = [postUrl stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
    
    // 1. 准备URL
    NSURL *url = [NSURL URLWithString:escapedString];
    
    // 2. 创建请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    
    
    [request setValue:[NSString stringWithFormat:@"%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]] forHTTPHeaderField:@"overhead"];
    [request setValue:[NSString stringWithFormat:@"%@",[DeviceModelUtil deviceMarketingName]] forHTTPHeaderField:@"locations"];
    [request setValue:[NSString stringWithFormat:@"%@",[AppTools getOrCreatePseudoIDFV]] forHTTPHeaderField:@"relative"];
    [request setValue:[NSString stringWithFormat:@"%@",[NSString stringWithFormat:@"%@",[[UIDevice currentDevice] systemVersion]]] forHTTPHeaderField:@"immediately"];
    [request setValue:[NSString stringWithFormat:@"%@",[AppTools getLoginToken]] forHTTPHeaderField:@"mitigate"];
    [request setValue:[NSString stringWithFormat:@"%@",[AppTools getIDFA]] forHTTPHeaderField:@"techniques"];
    [request setValue:[NSString stringWithFormat:@"%@",[AppTools getLoginCountry]] forHTTPHeaderField:@"narrowly"];

    // 3. 设置请求头
    
    // 4. 生成boundary（用于multipart分割）
    NSString *boundary = [NSString stringWithFormat:@"Boundary-%@", NSUUID.UUID.UUIDString];
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
    
    // 5. 构造请求体
    NSMutableData *body = [NSMutableData data];
    
    // 添加文本参数
    NSDictionary *textParams = params;
    
    [textParams enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", value] dataUsingEncoding:NSUTF8StringEncoding]];
    }];
    
    // 添加图片参数
    if (imageData) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"textLiteraturethis\"; filename=\"%@.jpg\"\r\n",imageName] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:imageData];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }
    
    // 结束标记
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    // 6. 设置请求体
    request.HTTPBody = body;
    
    // 7. 创建并启动任务
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:completion];
    [task resume];
}

// 构建multipart/form-data请求体
- (NSData *)createBodyWithBoundary:(NSString *)boundary image:(NSData *)imageData {
    NSMutableData *body = [NSMutableData data];
    
    // 添加图片数据
    if (imageData) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:imageData];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }
    
    // 添加其他字段
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Disposition: form-data; name=\"key\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"value\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    
    // 结束符
    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    return body;
}

- (void)getWithUrl:(NSString *)url params:(id)param succ:(SuccessBlock)succ fail:(FailureBlock)fail {
    [self configFailedNet];

    if (![url isEqualToString:@"/trains/simulate"] &&
        ![url isEqualToString:@"/trains/variety"] &&
        ![url isEqualToString:@"/trains/callback"] &&
        ![url isEqualToString:@"/trains/desire"] &&
        ![url isEqualToString:@"/trains/parent"]) {
        [SVProgressHUD show];
    }
    
    NSString *urlString = @"";
    if ([url isEqualToString:@"/trains/incorrect"]) {
        urlString = [NSString stringWithFormat:@"http://47.236.132.190/owner%@",url];
    }else {
        urlString = [NSString stringWithFormat:@"http://47.236.132.190/owner%@",url];
    }
    
    NSString *getUrl = [NSString stringWithFormat:@"%@?overhead=%@&locations=%@&relative=%@&immediately=%@&mitigate=%@&techniques=%@&narrowly=%@",urlString,[NSString stringWithFormat:@"%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]],[DeviceModelUtil deviceMarketingName],[AppTools getOrCreatePseudoIDFV],[NSString stringWithFormat:@"%@",[[UIDevice currentDevice] systemVersion]],[AppTools getLoginToken],[AppTools getIDFA],[AppTools getLoginCountry]];
    
    NSCharacterSet *allowedCharacterSet = [NSCharacterSet URLQueryAllowedCharacterSet];
    NSString *escapedString = [getUrl stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
    
    NSDictionary *headers = @{};
    
    [self.session GET:escapedString
            parameters:param
               headers:headers
              progress:nil
               success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (succ){
            NSString *rawString = [[NSString alloc] encodingData:responseObject];
            NSDictionary *responseDic = [AppTools dictionaryWithJsonString:rawString];
            DLog(@"Request========\n%@\n\nparam========\n%@\n\nresponseObject========\n%@",urlString,param,responseDic);
            NSString *interchangeably = [NSString stringWithFormat:@"%@",[responseDic safeObjectForKey:@"interchangeably"]];
            if ([interchangeably isEqualToString:@"-2"]) {
                [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"user_token"];
                [[NSUserDefaults standardUserDefaults] synchronize];
                
                [AppTools toLogin];
                [SVProgressHUD showErrorWithStatus:[Lang set:@"Login invalid"]];
                [SVProgressHUD dismissWithDelay:3.0f];

            }
            [SVProgressHUD dismiss];
            succ(responseDic);
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self hideTip];
        NSInteger errorType = ReqCodeTypeOther;
        if (error.code == NSURLErrorTimedOut) errorType = ReqCodeTypeTimeout;
        if (error.code == NSURLErrorCancelled) errorType = ReqCodeTypeCalceled;
        if (error.code == NSURLErrorNotConnectedToInternet || error.code == NSURLErrorCannotConnectToHost) errorType = ReqCodeTypeNoNetWork;
        
        if (errorType == ReqCodeTypeTimeout || errorType == ReqCodeTypeNoNetWork) {
            if (![url isEqualToString:@"/trains/simulate"] &&
                ![url isEqualToString:@"/trains/variety"] &&
                ![url isEqualToString:@"/trains/callback"] &&
                ![url isEqualToString:@"/trains/desire"] &&
                ![url isEqualToString:@"/trains/parent"]) {
                [SVProgressHUD showErrorWithStatus:[Lang set:@"There's an error in the network"]];
                [SVProgressHUD dismissWithDelay:3.0f];

            }
        }else{
            if (![url isEqualToString:@"/trains/simulate"] &&
                ![url isEqualToString:@"/trains/variety"] &&
                ![url isEqualToString:@"/trains/callback"] &&
                ![url isEqualToString:@"/trains/desire"] &&
                ![url isEqualToString:@"/trains/parent"]) {
                [SVProgressHUD showErrorWithStatus:[Lang set:@"Request failed"]];
                [SVProgressHUD dismissWithDelay:3.0f];

            }
        }
        if (fail) {
            fail(errorType,error);
        }
    }];
}

- (NSString *)urlString:(NSString *)string {
    return [NSString stringWithFormat:@"%@",BASE_URL];
}

- (NSString*)formatData:(NSDictionary *)dic{
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&error];
    NSString *jsonString;
    if (!jsonData) {
    }else{
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    return jsonString;
}

- (void)configFailedNet {
    [[AWHttpService service]reachBilityStatusWithCallBack:^(AFNetworkReachabilityStatus status) {
        if (status == 0) {
//            [SVProgressHUD showWithStatus:@"There is no network at present."];
        }
    }];
}

- (void)hideTip {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 隐藏hud
        [SVProgressHUD dismiss];
    });
}

- (void)cancelRequestWithURL:(NSString *)url {
    
    if (url == nil) {
        return;
    }
    
    @synchronized(self) {
        [[self allTasks] enumerateObjectsUsingBlock:^(NSURLSessionTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task isKindOfClass:[NSURLSessionTask class]]
                && [task.currentRequest.URL.absoluteString hasSuffix:url]) {
                [task cancel];
                [[self allTasks] removeObject:task];
                return;
            }
        }];
    };
}

- (void)cancelAllRequest {
    @synchronized(self) {
        [[self allTasks] enumerateObjectsUsingBlock:^(NSURLSessionTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task isKindOfClass:[NSURLSessionTask class]]) {
                [task cancel];
            }
        }];
        [[self allTasks] removeAllObjects];
    };
}

- (void)reachBilityStatusWithCallBack:(ReachBilityStatusBlock)block;{
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    [mgr  startMonitoring];
    [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        if (block) {
            block(status);
        }
    }];
    [mgr stopMonitoring];
}

- (AFHTTPSessionManager*)session{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!self->_session) {
             self->_session = [AFHTTPSessionManager manager];
            self->_session.responseSerializer = [AFHTTPResponseSerializer serializer];
            self->_session.requestSerializer.timeoutInterval = 10;

        }
    });
    return _session;
}
//-(AFHTTPSessionManager*)session{
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        if (!self->_session) {
//             self->_session = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//             self->_session.requestSerializer = [AFJSONRequestSerializer serializer];
//            [self->_session.requestSerializer setValue:@"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
//            self->_session.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain" ,@"multipart/form-data",nil];
//            self->_session.requestSerializer.timeoutInterval = 10;
//
//        }
//    });
//    return _session;
//}

- (NSMutableArray *)allTasks{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (gy_requestTasks == nil) {
            gy_requestTasks = [[NSMutableArray alloc] init];
        }
    });
    return gy_requestTasks;
}

@end
